package javaMultiThread;
/**
 * 
 * @author jieji
 *JAVA多线程艺术第二章
 */
/**
 *  方法内部的变量都是线程安全的

 *  synchronized持有对象锁,
 *  如果一个对象了有2个方法,一个加了关键字synchronized一个没有加
 *  那么加关键字的需要排队,没有加关键字的随便调用(这样就出现了dirtyRead)
 *  如果2个方法都加了关键字synchronized那么都要同步(这样把读写都加上对象锁就避免出现dirtyRead)
 *
 */
/**
 * (可重入锁)如果一个方法加了synchronized关键字  那么他调用这个对象的其它synchronized方法是一定可以获得这个对象的对象锁的
 * 可重入锁支持继承关系
 
 *当出现异常时锁自动释放 
 *
 */
/**
 * 同步不具有继承性
 * synchronized方法和synchronized(this)代码库都是锁定当前对象
 */
/**
 * synchronized加到static静态方法上的是Class锁
 * 加到非静态方法上的是对象锁
 * class锁可以对所有对象锁起作用(执行对象同步锁时是不影响的)
 * synchronized(x.class)和synchronized static方法作用是一样的
 *
 */
/**
 * synchronized方法不利益处理执行很久的方法,可用同步代码库解决
 *
 */
/**
 * 2个synchronized(非this锁)出现在代码块中交叉引用就会出现死锁(相互等待对方释放锁)
 *
 */
/**
 * 只要对象不变,对象中的属性边了synchronized还是同步
 *
 */
/**
 * volatitle作用是强制从公用堆栈中取值
 *
 */
public class Thread2 {

	public static void main(String[] args) {
		ThreadStaticEntity threadStaticEntity=new ThreadStaticEntity();
		ThreadStaticA a=new ThreadStaticA(threadStaticEntity);
		ThreadStaticB b=new ThreadStaticB(threadStaticEntity);
		a.start();
		b.start();
		
	}

}
class ThreadA implements Runnable{
	private Integer integer=0;

	@Override
	public void run() {		
		int num=0;
		synchronized (this) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				
				e.printStackTrace();
			}
			num++;
			integer++;
		}
		System.out.println(num);
		System.out.println(integer);
	}
	
}
class ThreadB extends Thread{

	@Override
	public void run() {		
		super.run();
		for(int i=0;i<100;i++){
			System.out.println(i);
		}
	}
	
}
class ThreadStaticA extends Thread{
	private ThreadStaticEntity threadStaticEntity;
	public ThreadStaticA(ThreadStaticEntity threadStaticEntity){
		this.threadStaticEntity=threadStaticEntity;
	}
	@Override
	public void run() {
		super.run();
		ThreadStaticEntity.t1();
	}
	public ThreadStaticEntity getThreadStaticEntity() {
		return threadStaticEntity;
	}
	public void setThreadStaticEntity(ThreadStaticEntity threadStaticEntity) {
		this.threadStaticEntity = threadStaticEntity;
	}
	

}
class ThreadStaticB extends Thread{
	private ThreadStaticEntity threadStaticEntity;
	public ThreadStaticB(ThreadStaticEntity threadStaticEntity){
		this.threadStaticEntity=threadStaticEntity;
	}
	@Override
	public void run() {
		super.run();
		threadStaticEntity.t2();
	}
	public ThreadStaticEntity getThreadStaticEntity() {
		return threadStaticEntity;
	}
	public void setThreadStaticEntity(ThreadStaticEntity threadStaticEntity) {
		this.threadStaticEntity = threadStaticEntity;
	}

}
class ThreadStaticEntity {
	public synchronized static void t1(){
		System.out.println("static start");
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			
			e.printStackTrace();
		}
		System.out.println("static end");
	}
	public synchronized void t2(){
		System.out.println("t2 start");
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			
			e.printStackTrace();
		}
	}
}
